Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[jsonrpc] fix estimated rewards during safe mode #20182

Merged
merged 2 commits into from
Nov 6, 2024

Conversation

emmazzz
Copy link
Contributor

@emmazzz emmazzz commented Nov 5, 2024

Description

Currently if the exchange rate for an epoch is not found, we would assign it the default exchange rate while we should've used the exchange rate from the previous existing epoch instead. This PR fixes that.

Test plan

Added some unit tests.


Release notes

Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required.

For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates.

  • Protocol:
  • Nodes (Validators and Full nodes):
  • Indexer:
  • JSON-RPC: fixed reward estimation in getStakes API so that we don't overestimate stake rewards of stakes activated during safe mode epochs.
  • GraphQL:
  • CLI:
  • Rust SDK:
  • REST API:

Copy link

vercel bot commented Nov 5, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
sui-docs ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 5, 2024 9:46pm
3 Skipped Deployments
Name Status Preview Comments Updated (UTC)
multisig-toolkit ⬜️ Ignored (Inspect) Visit Preview Nov 5, 2024 9:46pm
sui-kiosk ⬜️ Ignored (Inspect) Visit Preview Nov 5, 2024 9:46pm
sui-typescript-docs ⬜️ Ignored (Inspect) Visit Preview Nov 5, 2024 9:46pm

return rates;
}

let min_epoch = *rates.iter().map(|(e, _)| e).min().unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably easier to sort it first before processing.
But otherwise this code looks good to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if sorting it first will make things easier because then we'd have to keep track of the index we are at separately and insert the missing entry, etc. The logic may get messier. Unless I'm missing something.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You just iterate the sorted vector. No need for min/max/find calls.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the alternative implementation I came up with:

fn backfill_rates(
    mut rates: Vec<(EpochId, PoolTokenExchangeRate)>,
) -> Vec<(EpochId, PoolTokenExchangeRate)> {
    if rates.is_empty() {
        return rates;
    }

    rates.sort_by(|(a, _), (b, _)| a.cmp(b));
    let mut filled_rates = vec![];


    let mut next_epoch_to_fill = rates[0].0;
    let mut prev_rate = rates[0].1.clone();
    for (epoch, rate) in rates {
        // Fill in all the gaps between the previous entry and the current entry.
        while epoch > next_epoch_to_fill {
            filled_rates.push((next_epoch_to_fill, prev_rate.clone()));
            next_epoch_to_fill += 1;
        }
        filled_rates.push((next_epoch_to_fill, rate.clone()));
        next_epoch_to_fill += 1;
        prev_rate = rate;
    }

    filled_rates.reverse();
    filled_rates
}

I think this is harder to understand and get right. It took me quite a few tries to get the code right, with off-by-one errors etc

@@ -431,7 +432,8 @@ async fn exchange_rates(
})
.collect::<Result<Vec<_>, _>>()?;

rates.sort_by(|(a, _), (b, _)| a.cmp(b).reverse());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is line 466/467 attempting to do the equivalent of this?

Copy link
Contributor Author

@emmazzz emmazzz Nov 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The loop in backfill_rates does backfilling + sorting in ascending order by epoch number. And line 484 reverses the vector so it becomes sorted in descending order.

@emmazzz emmazzz merged commit 27098db into main Nov 6, 2024
52 checks passed
@emmazzz emmazzz deleted the emma/fix-reward-estimate branch November 6, 2024 00:13
emmazzz added a commit that referenced this pull request Nov 6, 2024
## Description 

Currently if the exchange rate for an epoch is not found, we would
assign it the default exchange rate while we should've used the exchange
rate from the previous existing epoch instead. This PR fixes that.

## Test plan 

Added some unit tests.

---

## Release notes

Check each box that your changes affect. If none of the boxes relate to
your changes, release notes aren't required.

For each box you select, include information after the relevant heading
that describes the impact of your changes that a user might notice and
any actions they must take to implement updates.

- [ ] Protocol: 
- [ ] Nodes (Validators and Full nodes): 
- [ ] Indexer: 
- [x] JSON-RPC: fixed reward estimation in `getStakes` API so that we
don't overestimate stake rewards of stakes activated during safe mode
epochs.
- [ ] GraphQL: 
- [ ] CLI: 
- [ ] Rust SDK:
- [ ] REST API:
emmazzz added a commit that referenced this pull request Nov 6, 2024
## Description 

Currently if the exchange rate for an epoch is not found, we would
assign it the default exchange rate while we should've used the exchange
rate from the previous existing epoch instead. This PR fixes that.

## Test plan 

Added some unit tests.

---

## Release notes

Check each box that your changes affect. If none of the boxes relate to
your changes, release notes aren't required.

For each box you select, include information after the relevant heading
that describes the impact of your changes that a user might notice and
any actions they must take to implement updates.

- [ ] Protocol: 
- [ ] Nodes (Validators and Full nodes): 
- [ ] Indexer: 
- [x] JSON-RPC: fixed reward estimation in `getStakes` API so that we
don't overestimate stake rewards of stakes activated during safe mode
epochs.
- [ ] GraphQL: 
- [ ] CLI: 
- [ ] Rust SDK:
- [ ] REST API:
emmazzz added a commit that referenced this pull request Nov 6, 2024
## Description 

Currently if the exchange rate for an epoch is not found, we would
assign it the default exchange rate while we should've used the exchange
rate from the previous existing epoch instead. This PR fixes that.

## Test plan 

Added some unit tests.

---

## Release notes

Check each box that your changes affect. If none of the boxes relate to
your changes, release notes aren't required.

For each box you select, include information after the relevant heading
that describes the impact of your changes that a user might notice and
any actions they must take to implement updates.

- [ ] Protocol: 
- [ ] Nodes (Validators and Full nodes): 
- [ ] Indexer: 
- [x] JSON-RPC: fixed reward estimation in `getStakes` API so that we
don't overestimate stake rewards of stakes activated during safe mode
epochs.
- [ ] GraphQL: 
- [ ] CLI: 
- [ ] Rust SDK:
- [ ] REST API:
@@ -451,6 +453,38 @@ pub struct ValidatorExchangeRates {
pub rates: Vec<(EpochId, PoolTokenExchangeRate)>,
}

/// Backfill missing rates for some epochs due to safe mode. If a rate is missing for epoch e,
/// we will use the rate for epoch e-1 to fill it.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"we will use the value from the nearest prior epoch"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants